/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package de.blitzcoder.collide.gui;


import java.io.File;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

/**
 *
 * @author blitzcoder
 */
public abstract class Document extends JPanel {
    
    // The Title of the DocumentTab
    public abstract String getTitle();
    
    // Method is called if tab is closed
    // Tab is only closed if true is returnes
    public boolean close() { return true; };

    // Icon
    public abstract Icon getIcon();

    // ToolTip
    public abstract String getToolTip();

    // Document got focus
    public void focus() {}

    // Document was inserted
    public void documentInserted(JPopupMenu popupMenu) {}

    // Checks if a document is already open.
    public abstract boolean equalsFile(File file);

    // Load the content of the document, init the layout and so on
    // This Method is called by the DocumentManager in an extra thread
    // The initialization should NOT be done in the constructor
    public void load() throws Exception {}

    // This is called after loading and initialisation of the Document
    // has finished
    protected boolean finishedLoading = false;
    public final void afterLoad() {
        finishedLoading = true;
        ListIterator<Runnable> it = queue.listIterator();
        while (it.hasNext())
            SwingUtilities.invokeLater(it.next());
        queue.clear();
    }

    // fireDocumentUpdate should be called when title, icon or tooltip changes
    LinkedList<UpdateListener> updateListenerList = new LinkedList<UpdateListener>();
    public interface UpdateListener {
        public void update(Document doc);
    }
    protected final void fireDocumentUpdate() {
        ListIterator<UpdateListener> it = updateListenerList.listIterator();
        while (it.hasNext()) {
            it.next().update(this);
        }
    }
    public final void addUpdateListener(UpdateListener l) {
        updateListenerList.addLast(l);
    }

    // You can pass in runnables which are run after the load
    // If already finished Loading, they are imideatly run
    // The runnables are run in the event dispatcher thread
    LinkedList<Runnable> queue = new LinkedList<Runnable>();
    public synchronized final void schedule(Runnable run) {
        if (finishedLoading) {
            SwingUtilities.invokeLater(run);
            return;
        }
        queue.addLast(run);
    }

    /*
     * Clone stuff
     */
    public boolean isClonable() {
        return false;
    }

    public Document cloneDocument() {
        throw new UnsupportedOperationException("Cloning not supported");
    }

    public boolean isClone() {
        return false;
    }

    public Document getOriginal() {
        throw new UnsupportedOperationException("Not a clone");
    }

}
